package com.xyz.service.impl;

import cn.hutool.core.collection.CollStreamUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.xyz.config.SystemData;
import com.xyz.contant.PartApplyStateEnum;
import com.xyz.controller.vo.InStockVO;
import com.xyz.entity.mapper.*;
import com.xyz.entity.pojo.*;
import com.xyz.service.CommonService;
import com.xyz.service.FileService;
import com.xyz.service.PartInnStockService;
import com.xyz.service.PartService;
import com.xyz.util.dto.DataResult;
import com.xyz.util.dto.GridData;
import com.xyz.util.dto.LoginInfo;
import com.xyz.vo.PartInnOrderDetailVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

import static com.xyz.contant.Constant.*;

@Service
@Transactional(rollbackFor = Exception.class)
public class PartServiceImpl implements PartService {

    @Autowired
    private CommonService commonService;

    @Autowired
    private SystemParameterMapper systemParameterMapper;

    @Autowired
    private SystemEmployeeMapper systemEmployeeMapper;

    @Autowired
    private SystemFileMapper systemFileMapper;

    @Autowired
    private FileService fileService;

    @Autowired
    private PartWarehouseMapper partWarehouseMapper;

    @Autowired
    private PartInfoMapper partInfoMapper;

    @Autowired
    private PartStockMapper partStockMapper;

    @Autowired
    private PartEquipmentMapper partEquipmentMapper;

    @Autowired
    private PartApplyMapper partApplyMapper;

    @Autowired
    private PartApplyDetailMapper partApplyDetailMapper;

    @Autowired
    private PartApplyLogMapper partApplyLogMapper;

    @Autowired
    private PartOrderMapper partOrderMapper;

    @Autowired
    private PartOrderDetailMapper partOrderDetailMapper;

    @Autowired
    private PartInventoryMapper partInventoryMapper;

    @Autowired
    private PartInventoryDetailMapper partInventoryDetailMapper;

    @Autowired
    private BusinessFileMapper businessFileMapper;

    @Autowired
    private EquipmentInfoMapper equipmentInfoMapper;

    @Autowired
    private PartInnStockService partInnStockService;
    @Autowired
    private PartInnOrderMapper partInnOrderMapper;

    @Autowired
    private PartInnOrderDetailMapper partInnOrderDetailMapper;

    @Autowired
    private PartInnStockMapper partInnStockMapper;

    @Override
    public DataResult selectPartWarehouseLink(LoginInfo li) throws Exception {
        List<Map<String, Object>> list = new ArrayList<>();

        List<PartWarehouse> pwOneList = new ArrayList<>();
        List<PartWarehouse> pwTwoList = new ArrayList<>();

        PartWarehouseExample pwExample = new PartWarehouseExample();
        pwExample.setOrderByClause("sort");
        List<PartWarehouse> pwList = partWarehouseMapper.selectByExample(pwExample);
        for (PartWarehouse pw : pwList) {
            if (pw.getType() == 0) {
                pwOneList.add(pw);
            } else {
                pwTwoList.add(pw);
            }
        }
        for (PartWarehouse pwOne : pwOneList) {
            Map<String, Object> oneMap = new HashMap<>();
            oneMap.put("id", pwOne.getId());
            oneMap.put("name", pwOne.getName());
            List<Map<String, Object>> towList = new ArrayList<>();
            for (PartWarehouse pwTwo : pwTwoList) {
                if (pwTwo.getBaseId().equals(pwOne.getId())) {
                    Map<String, Object> twoMap = new HashMap<>();
                    twoMap.put("id", pwTwo.getId());
                    twoMap.put("name", pwTwo.getName());
                    towList.add(twoMap);
                }
            }
            oneMap.put("children", towList);
            list.add(oneMap);
        }
        return DataResult.build9100(list);
    }

    @Override
    public DataResult selectPartWarehouseLinkUnused(LoginInfo li, long partId) throws Exception {
        List<PartStock> psList = partStockMapper.selectByExample(null);
        List<Long> partIdList = CollStreamUtil.toList(psList, PartStock::getLocator);

        List<Map<String, Object>> list = new ArrayList<>();

        List<PartWarehouse> pwOneList = new ArrayList<>();
        List<PartWarehouse> pwTwoList = new ArrayList<>();

        PartWarehouseExample pwExample = new PartWarehouseExample();
        pwExample.setOrderByClause("sort");
        List<PartWarehouse> pwList = partWarehouseMapper.selectByExample(pwExample);
        for (PartWarehouse pw : pwList) {
            if (pw.getType() == 0) {
                pwOneList.add(pw);
            } else {
                pwTwoList.add(pw);
            }
        }
        a:
        for (PartWarehouse pwOne : pwOneList) {
            Map<String, Object> oneMap = new HashMap<>();
            oneMap.put("id", pwOne.getId());
            oneMap.put("name", pwOne.getName());
            List<Map<String, Object>> towList = new ArrayList<>();
            b:
            for (PartWarehouse pwTwo : pwTwoList) {
                if (pwTwo.getBaseId().equals(pwOne.getId())) {
                    if (partIdList.contains(pwTwo.getId())) {
                        continue b;
                    }
                    Map<String, Object> twoMap = new HashMap<>();
                    twoMap.put("id", pwTwo.getId());
                    twoMap.put("name", pwTwo.getName());
                    towList.add(twoMap);
                }
            }
            oneMap.put("children", towList);
            list.add(oneMap);
        }
        Iterator<Map<String, Object>> iterator = list.iterator();
        while (iterator.hasNext()) {
            Map<String, Object> next = iterator.next();
            List<Map<String, Object>> children = (List<Map<String, Object>>) next.get("children");
            if (children.size() == 0) {
                iterator.remove();
            }
        }
        return DataResult.build9100(list);
    }

    @Override
    public DataResult selectPartStockLink(LoginInfo li, long partId) throws Exception {
        PartStockExample psExample = new PartStockExample();
        psExample.createCriteria().andPartIdEqualTo(partId);
        List<PartStock> psList = partStockMapper.selectByExample(psExample);
        Set<Long> warehouseIdSet = new HashSet<>();
        Map<Long, Long> warehouseMap = new HashMap<>();
        for (PartStock ps : psList) {
            warehouseIdSet.add(ps.getWarehouse());
            warehouseIdSet.add(ps.getLocator());
            warehouseMap.put(ps.getLocator(), ps.getId());
        }

        List<Map<String, Object>> list = new ArrayList<>();
        if (warehouseIdSet.size() == 0) {
            return DataResult.build9100(list);
        }

        List<PartWarehouse> pwOneList = new ArrayList<>();
        List<PartWarehouse> pwTwoList = new ArrayList<>();

        PartWarehouseExample pwExample = new PartWarehouseExample();
        pwExample.createCriteria().andIdIn(CollUtil.newArrayList(warehouseIdSet));
        pwExample.setOrderByClause("sort");
        List<PartWarehouse> pwList = partWarehouseMapper.selectByExample(pwExample);
        for (PartWarehouse pw : pwList) {
            if (pw.getType() == 0) {
                pwOneList.add(pw);
            } else {
                pwTwoList.add(pw);
            }
        }
        for (PartWarehouse pwOne : pwOneList) {
            Map<String, Object> oneMap = new HashMap<>();
            oneMap.put("id", pwOne.getId());
            oneMap.put("name", pwOne.getName());
            List<Map<String, Object>> towList = new ArrayList<>();
            for (PartWarehouse pwTwo : pwTwoList) {
                if (pwTwo.getBaseId().equals(pwOne.getId())) {
                    Map<String, Object> twoMap = new HashMap<>();
                    twoMap.put("id", pwTwo.getId());
                    twoMap.put("name", pwTwo.getName());
                    twoMap.put("qrCodeStr", "EAM_STOCK_" + partId + "_" + warehouseMap.get(pwTwo.getId()));
                    twoMap.put("stockId", warehouseMap.get(pwTwo.getId()));
                    towList.add(twoMap);
                }
            }
            oneMap.put("children", towList);
            list.add(oneMap);
        }
        return DataResult.build9100(list);
    }

    @Override
    public DataResult selectPart(LoginInfo li, int pageNum, int pageSize, String tech,
                                 String codeOrName, String nature, String minPrice, String maxPrice, String minStock, String maxStock,
    String teamGroup) throws Exception {
        PartInfoExample piExample = new PartInfoExample();
        PartInfoExample.Criteria piCriteria1 = piExample.createCriteria();
        PartInfoExample.Criteria piCriteria2 = piExample.or();
        if (StrUtil.isNotBlank(tech)) {
            piCriteria1.andTechEqualTo(Integer.parseInt(tech));
            piCriteria2.andTechEqualTo(Integer.parseInt(tech));
        }
        if (StrUtil.isNotBlank(codeOrName)) {
            piCriteria1.andCodeLike("%" + codeOrName + "%");
            piCriteria2.andNameLike("%" + codeOrName + "%");
        }
        if (StrUtil.isNotBlank(nature)) {
            piCriteria1.andNatureEqualTo(Integer.parseInt(nature));
            piCriteria2.andNatureEqualTo(Integer.parseInt(nature));
        }
        if (StrUtil.isNotBlank(minPrice)) {
            piCriteria1.andPriceGreaterThanOrEqualTo(new BigDecimal(minPrice));
            piCriteria2.andPriceGreaterThanOrEqualTo(new BigDecimal(minPrice));
        }
        if (StrUtil.isNotBlank(maxPrice)) {
            piCriteria1.andPriceLessThanOrEqualTo(new BigDecimal(maxPrice));
            piCriteria2.andPriceLessThanOrEqualTo(new BigDecimal(maxPrice));
        }
        if (StrUtil.isNotBlank(minStock)) {
            piCriteria1.andStockGreaterThanOrEqualTo(Integer.parseInt(minStock));
        }
        if (StrUtil.isNotBlank(maxStock)) {
            piCriteria1.andStockLessThanOrEqualTo(Integer.parseInt(maxStock));
        }
        if (StrUtil.isNotBlank(maxStock)) {
            piCriteria1.andStockLessThanOrEqualTo(Integer.parseInt(maxStock));
        }
        if (StrUtil.isNotBlank(teamGroup)) {
            piCriteria1.andTeamGroupEqualTo(teamGroup);
            piCriteria2.andTeamGroupEqualTo(teamGroup);
        }
        piCriteria1.andIsDeleteEqualTo(0);
        piExample.setOrderByClause("update_time desc");
        Page<PartInfo> page = PageHelper.startPage(pageNum, pageSize);
        List<PartInfo> piList = partInfoMapper.selectByExample(piExample);

        List<PartInnStock> partInnStocks = CollUtil.newArrayList();
        List<Long> partIdList = piList.stream().map(PartInfo::getId).collect(Collectors.toList());
        if (CollUtil.isNotEmpty(partIdList)) {
            partInnStocks = partInnStockMapper.selectByPartIdList(partIdList);
        }
        List<Map<String, Object>> list = new ArrayList<>();
        for (PartInfo pi : piList) {
            Map<String, Object> map = new HashMap<>();
            Integer stock = findPartInnStocks(partInnStocks, pi.getId());
            map.put("id", pi.getId());
            map.put("code", pi.getCode());
            map.put("name", pi.getName());
            map.put("specs", pi.getSpecs());
            map.put("brand", pi.getBrand());
            map.put("unit", pi.getUnit());
            map.put("price", pi.getPrice().toPlainString());
            map.put("stock", pi.getStock() + stock);
            map.put("warnStock", pi.getWarnStock());
            map.put("maxStock", pi.getMaxStock());
            map.put("nature", pi.getNature());
            map.put("tech", pi.getTech());
            map.put("useStock", (pi.getStock() + stock) - pi.getTransitStock());
            map.put("specification", pi.getSpecification());
            map.put("teamGroup", pi.getTeamGroup() == null ? null : Integer.parseInt(pi.getTeamGroup()));
            list.add(map);
        }
        return DataResult.build9100(new GridData(page.getTotal(), list));
    }

    private Integer findPartInnStocks(List<PartInnStock> partInnStocks, Long partId) {
        for (PartInnStock partInnStock : partInnStocks) {
            if (partInnStock.getPartId().equals(partId)) {
                return partInnStock.getStock();
            }
        }
        return 0;
    }

    @Override
    public DataResult selectPartInfo(LoginInfo li, long id) throws Exception {
        PartInfo pi = partInfoMapper.selectByPrimaryKey(id);
        Map<String, Object> map = new HashMap<>();
        map.put("id", pi.getId());
        map.put("code", pi.getCode());
        map.put("name", pi.getName());
        map.put("specs", pi.getSpecs());
        map.put("brand", pi.getBrand());
        map.put("unit", pi.getUnit());
        map.put("price", pi.getPrice().toPlainString());
        map.put("stock", pi.getStock());
        map.put("warnStock", pi.getWarnStock());
        map.put("maxStock", pi.getMaxStock());
        map.put("nature", pi.getNature());
        map.put("tech", pi.getTech());
        map.put("teamGroup", pi.getTeamGroup() == null ? null : Integer.parseInt(pi.getTeamGroup()));
        map.put("specification", pi.getSpecification());
        return DataResult.build9100(map);
    }

    @Override
    public DataResult insertPartInfo(
            LoginInfo li, String code, String name, String specs, String brand, String unit, String
            price, int warnStock, int maxStock, int nature, int tech
            ,String teamGroup,String specification
    ) throws Exception {
        Date date = new Date();
        PartInfo newPi1 = new PartInfo();
        newPi1.setCode(code);
        newPi1.setName(name);
        newPi1.setSpecs(specs);
        newPi1.setBrand(brand);
        newPi1.setUnit(unit);
        newPi1.setPrice(new BigDecimal(price));
        newPi1.setStock(0);
        newPi1.setTransitStock(0);
        newPi1.setWarnStock(warnStock);
        newPi1.setMaxStock(maxStock);
        newPi1.setNature(nature);
        newPi1.setTech(tech);
        newPi1.setPartDesc("");
        newPi1.setIsDelete(0);
        newPi1.setUpdateEmployeeId(li.getLoginEmployeeId());
        newPi1.setUpdateTime(date);
        newPi1.setCreateEmployeeId(li.getLoginEmployeeId());
        newPi1.setCreateTime(date);
        newPi1.setTeamGroup(teamGroup);
        newPi1.setSpecification(specification);
        partInfoMapper.insert(newPi1);
        return DataResult.build9100(newPi1.getId());
    }

    @Override
    public DataResult updatePartInfo(
            LoginInfo li, long id, String code, String name, String specs, String brand, String
            unit, String price, int stock, int warnStock, int maxStock, int nature, int tech
            ,String teamGroup,String specification
    ) throws Exception {
        Date date = new Date();
        PartInfo newPi = new PartInfo();
        newPi.setId(id);
        newPi.setCode(code);
        newPi.setName(name);
        newPi.setSpecs(specs);
        newPi.setBrand(brand);
        newPi.setUnit(unit);
        newPi.setPrice(new BigDecimal(price));
        newPi.setStock(stock);
        newPi.setWarnStock(warnStock);
        newPi.setMaxStock(maxStock);
        newPi.setNature(nature);
        newPi.setTech(tech);
        newPi.setUpdateEmployeeId(li.getLoginEmployeeId());
        newPi.setUpdateTime(date);
        newPi.setTeamGroup(teamGroup);
        newPi.setSpecification(specification);
        partInfoMapper.updateByPrimaryKeySelective(newPi);
        return DataResult.build9100();
    }

    @Override
    public DataResult deletePartInfo(LoginInfo li, long id) throws Exception {
        Date date = new Date();
        PartInfo pi = new PartInfo();
        pi.setId(id);
        pi.setIsDelete(1);
        pi.setUpdateEmployeeId(li.getLoginEmployeeId());
        pi.setUpdateTime(date);
        partInfoMapper.updateByPrimaryKeySelective(pi);
        return DataResult.build9100();
    }

    @Override
    public DataResult selectPartData(LoginInfo li, long id) throws Exception {
        PartInfo pi = partInfoMapper.selectByPrimaryKey(id);

        List<String> fileCodeList = new ArrayList<>();
        BusinessFileExample bfExample = new BusinessFileExample();
        BusinessFileExample.Criteria bfCriteria = bfExample.createCriteria();
        bfCriteria.andBusTablesIdEqualTo(pi.getId());
        bfCriteria.andBusTypeEqualTo(5);
        bfCriteria.andFileGroupEqualTo(1);
        bfCriteria.andFileTypeEqualTo(1);
        List<BusinessFile> bfList = businessFileMapper.selectByExample(bfExample);
        for (BusinessFile bf : bfList) {
            fileCodeList.add(bf.getFileCode());
        }

        Map<String, Object> map = new HashMap<>();
        map.put("partDesc", pi.getPartDesc());
        map.put("fileCodes", fileCodeList);
        map.put("updateEmployeeName", SystemData.employeeMap.get(pi.getUpdateEmployeeId()).getEmployeeName());
        map.put("updateTime", DateUtil.formatDateTime(pi.getUpdateTime()));
        map.put("createEmployeeName", SystemData.employeeMap.get(pi.getCreateEmployeeId()).getEmployeeName());
        map.put("createTime", DateUtil.formatDateTime(pi.getCreateTime()));
        return DataResult.build9100(map);
    }

    @Override
    public DataResult updatePartData(LoginInfo li, long id, String partDesc, String fileCodes) throws Exception {
        PartInfo newPi = new PartInfo();
        newPi.setId(id);
        newPi.setPartDesc(StrUtil.isBlank(partDesc) ? "" : partDesc);
        partInfoMapper.updateByPrimaryKeySelective(newPi);

        BusinessFileExample bfExample = new BusinessFileExample();
        BusinessFileExample.Criteria bfCriteria = bfExample.createCriteria();
        bfCriteria.andBusTablesIdEqualTo(id);
        bfCriteria.andBusTypeEqualTo(5);
        bfCriteria.andFileGroupEqualTo(1);
        bfCriteria.andFileTypeEqualTo(1);
        businessFileMapper.deleteByExample(bfExample);

        if (StrUtil.isNotBlank(fileCodes)) {
            Date date = new Date();
            for (String fileCode : fileCodes.split(",")) {
                BusinessFile newBf = new BusinessFile();
                newBf.setBusTablesId(id);
                newBf.setBusType(5);
                newBf.setFileGroup(1);
                newBf.setFileCode(fileCode);
                newBf.setFileType(1);
                newBf.setEmployeeId(li.getLoginEmployeeId());
                newBf.setUpdateTime(date);
                newBf.setCreateTime(date);
                businessFileMapper.insert(newBf);
            }
        }
        return DataResult.build9100();
    }

    @Override
    public DataResult selectPartEquipment(LoginInfo li, int pageNum, int pageSize, long id) throws Exception {
        Map<Integer, String> typeEmGrade = commonService.getDictMap("TYPE_EM_GRADE");
        Map<Integer, String> typeEmState = commonService.getDictMap("TYPE_EM_STATE");

        PartEquipmentExample peExample = new PartEquipmentExample();
        peExample.createCriteria().andPartIdEqualTo(id);
        Page<PartEquipment> page = PageHelper.startPage(pageNum, pageSize);
        List<PartEquipment> peList = partEquipmentMapper.selectByExample(peExample);
        List<Map<String, Object>> list = new ArrayList<>();
        for (PartEquipment pe : peList) {
            EquipmentInfo ei = equipmentInfoMapper.selectByPrimaryKey(pe.getEquipmentId());
            Map<String, Object> map = new HashMap<>();
            map.put("id", pe.getId());
            map.put("emCode", ei.getEmCode());
            map.put("emName", ei.getEmName());
            map.put("emGrade", typeEmGrade.get(ei.getEmGrade()));
            map.put("emState", typeEmState.get(ei.getEmState()));
            list.add(map);
        }
        return DataResult.build9100(new GridData(page.getTotal(), list));
    }

    @Override
    public DataResult insertPartEquipment(LoginInfo li, long id, String equipmentIds) throws Exception {
        for (String equipmentIdStr : equipmentIds.split(",")) {
            PartEquipment newPe = new PartEquipment();
            newPe.setPartId(id);
            newPe.setEquipmentId(Long.parseLong(equipmentIdStr));
            partEquipmentMapper.insert(newPe);
        }
        return DataResult.build9100();
    }

    @Override
    public DataResult deletePartEquipment(LoginInfo li, String ids) throws Exception {
        for (String idStr : ids.split(",")) {
            partEquipmentMapper.deleteByPrimaryKey(Long.parseLong(idStr));
        }
        return DataResult.build9100();
    }

    @Override
    public DataResult selectPartInOutLog(LoginInfo li, int pageNum, int pageSize, long id) throws Exception {
        Map<Integer, String> dictMap = commonService.getDictMap("TYPE_PART_IN_TYPE", "TYPE_PART_OUT_TYPE");

        PartOrderDetailExample podExample = new PartOrderDetailExample();
        podExample.createCriteria().andPartIdEqualTo(id);
        List<PartOrderDetail> podList = partOrderDetailMapper.selectByExample(podExample);
        Map<Long, Integer> partMap = new HashMap<>();
        for (PartOrderDetail pod : podList) {
            if (partMap.containsKey(pod.getOrderId())) {
                partMap.put(pod.getOrderId(), partMap.get(pod.getOrderId()) + pod.getInOutNum());
            } else {
                partMap.put(pod.getOrderId(), pod.getInOutNum());
            }
        }
        partMap.put(0L, 0);
        PartOrderExample poExample = new PartOrderExample();
        poExample.createCriteria().andIdIn(CollUtil.newArrayList(partMap.keySet())).andStateEqualTo(0);
        poExample.setOrderByClause("operation_time desc");
        Page<PartOrder> page = PageHelper.startPage(pageNum, pageSize);
        List<PartOrder> poList = partOrderMapper.selectByExample(poExample);
        List<Map<String, Object>> list = new ArrayList<>();
        for (PartOrder po : poList) {
            Map<String, Object> map = new HashMap<>();
            map.put("orderCode", po.getOrderCode());
            map.put("orderType", po.getOrderType() == 0 ? "备件单入库" : "备件单出库");
            map.put("businessType", dictMap.get(po.getInOutType()));
            map.put("num", partMap.get(po.getId()));
            map.put("operationTime", DateUtil.formatDateTime(po.getOperationTime()));
            list.add(map);
        }
        return DataResult.build9100(new GridData(page.getTotal(), list));

    }

    @Override
    public DataResult selectPartTransitLog(LoginInfo li, int pageNum, int pageSize, long id) throws Exception {
        Map<Integer, String> outTypeMap = commonService.getDictMap("TYPE_PART_OUT_TYPE");

        PartApplyExample paExample = new PartApplyExample();
        PartApplyExample.Criteria paCriteria = paExample.createCriteria();
        paCriteria.andStateIn(Arrays.asList(1, 2));
        paCriteria.andIsDeleteEqualTo(0);
        paExample.setOrderByClause("apply_time desc");
        Page<PartApply> page = PageHelper.startPage(pageNum, pageSize);
        List<PartApply> paList = partApplyMapper.selectByExample(paExample);
        List<Map<String, Object>> list = new ArrayList<>();
        for (PartApply pa : paList) {
            Map<String, Object> map = new HashMap<>();
            map.put("id", pa.getId());
            map.put("applyCode", pa.getApplyCode());
            map.put("outType", outTypeMap.get(pa.getOutType()));
            map.put("employeeName", SystemData.employeeMap.get(pa.getApplyEmployeeId()).getEmployeeName());
            map.put("applyTime", DateUtil.formatDateTime(pa.getApplyTime()));
            map.put("state", pa.getState());
            map.put("partClass", pa.getPartClass());
            map.put("partNum", pa.getPartNum());
            list.add(map);
        }
        return DataResult.build9100(new GridData(page.getTotal(), list));
    }

    @Override
    public DataResult selectPartStock(LoginInfo li, int pageNum, int pageSize, long id) throws Exception {
        Map<Long, String> warehouseMap = new HashMap<>();
        List<PartWarehouse> pwList = partWarehouseMapper.selectByExample(null);
        for (PartWarehouse pw : pwList) {
            warehouseMap.put(pw.getId(), pw.getName());
        }

        PartStockExample psExample = new PartStockExample();
        psExample.createCriteria().andPartIdEqualTo(id);
        Page<PartStock> page = PageHelper.startPage(pageNum, pageSize);
        List<PartStock> psList = partStockMapper.selectByExample(psExample);
        List<Map<String, Object>> list = new ArrayList<>();
        for (PartStock ps : psList) {
            Map<String, Object> map = new HashMap<>();
            map.put("id", ps.getId());
            map.put("warehouse", warehouseMap.get(ps.getWarehouse()));
            map.put("locator", warehouseMap.get(ps.getLocator()));
            map.put("stock", ps.getStock());
            list.add(map);
        }
        return DataResult.build9100(new GridData(page.getTotal(), list));
    }


    @Override
    public DataResult insertPartStock(LoginInfo li, long id, long warehouse, long locator) throws Exception {
        PartStockExample psExample = new PartStockExample();
        psExample.createCriteria().andWarehouseEqualTo(warehouse).andLocatorEqualTo(locator);
        if (partStockMapper.countByExample(psExample) > 0) {
            return DataResult.build9250("该库位已被其他备件绑定");
        }
        PartStock newPs = new PartStock();
        newPs.setPartId(id);
        newPs.setWarehouse(warehouse);
        newPs.setLocator(locator);
        newPs.setStock(0);
        newPs.setIsDelete(0);
        partStockMapper.insert(newPs);
        return DataResult.build9100();
    }

    @Override
    public DataResult deletePartStock(LoginInfo li, long id) throws Exception {
        PartStock ps = partStockMapper.selectByPrimaryKey(id);
        if (ps.getStock() > 0) {
            return DataResult.build9250("库存数量大于0无法删除");
        }
        PartStock newPs = new PartStock();
        newPs.setPartId(id);
        newPs.setIsDelete(1);
        partStockMapper.updateByPrimaryKeySelective(newPs);
        return DataResult.build9100();
    }

    @Override
    public DataResult selectPartDocument(LoginInfo li, int pageNum, int pageSize, long id) throws Exception {
        BusinessFileExample bfExample = new BusinessFileExample();
        BusinessFileExample.Criteria bfCriteria = bfExample.createCriteria();
        bfCriteria.andBusTablesIdEqualTo(id);
        bfCriteria.andBusTypeEqualTo(5);
        bfCriteria.andFileGroupEqualTo(2);
        bfCriteria.andFileTypeEqualTo(4);
        bfExample.setOrderByClause("create_time");
        Page<BusinessFile> page = PageHelper.startPage(pageNum, pageSize);
        List<BusinessFile> bfList = businessFileMapper.selectByExample(bfExample);
        List<Map<String, Object>> list = new ArrayList<>();
        for (BusinessFile bf : bfList) {
            SystemFile sf = systemFileMapper.selectByPrimaryKey(bf.getFileCode());
            Map<String, Object> map = new HashMap<>();
            map.put("id", bf.getId());
            map.put("fileCode", bf.getFileCode());
            map.put("fileName", sf == null ? "" : sf.getFileName());
            map.put("employeeName", SystemData.employeeMap.get(bf.getEmployeeId()).getEmployeeName());
            map.put("createTime", DateUtil.formatDateTime(bf.getCreateTime()));
            list.add(map);
        }
        return DataResult.build9100(new GridData(page.getTotal(), list));
    }

    @Override
    public DataResult insertPartDocument(LoginInfo li, long id, String fileCodes) throws Exception {
        if (StrUtil.isNotBlank(fileCodes)) {
            Date date = new Date();
            for (String fileCode : fileCodes.split(",")) {
                BusinessFile newBf = new BusinessFile();
                newBf.setBusTablesId(id);
                newBf.setBusType(5);
                newBf.setFileGroup(2);
                newBf.setFileCode(fileCode);
                newBf.setFileType(4);
                newBf.setEmployeeId(li.getLoginEmployeeId());
                newBf.setUpdateTime(date);
                newBf.setCreateTime(date);
                businessFileMapper.insert(newBf);
            }
        }
        return DataResult.build9100();
    }

    @Override
    public DataResult deletePartDocument(LoginInfo li, long id) throws Exception {
        BusinessFile bf = businessFileMapper.selectByPrimaryKey(id);
        fileService.deleteFile(li, bf.getFileCode());
        businessFileMapper.deleteByPrimaryKey(bf.getId());
        return DataResult.build9100();
    }

    @Override
    public DataResult selectStockInfo(LoginInfo li, long id) throws Exception {
        PartStock ps = partStockMapper.selectByPrimaryKey(id);
        PartInfo pi = partInfoMapper.selectByPrimaryKey(ps.getPartId());
        Map<String, Object> map = new HashMap<>();
        map.put("id", pi.getId());
        map.put("code", pi.getCode());
        map.put("name", pi.getName());
        map.put("specs", pi.getSpecs());
        map.put("warehouse", partWarehouseMapper.selectByPrimaryKey(ps.getWarehouse()).getName());
        map.put("locator", partWarehouseMapper.selectByPrimaryKey(ps.getLocator()).getName());
        return DataResult.build9100(map);
    }

    @Override
    public DataResult insertPartIn(LoginInfo li, int inType, String data) throws Exception {
        for (Object obj : JSONUtil.parseArray(data)) {
            JSONObject jsonObj = JSONUtil.parseObj(obj);
            long stockId = jsonObj.getLong("stockId");
            PartStock ps = partStockMapper.selectByPrimaryKey(stockId);
            if (ps != null && isPartInventory(ps.getWarehouse())) {
                return DataResult.build9250("仓库正在盘点中，无法入库");
            }
        }


        Date date = new Date();
        PartOrder newPo = new PartOrder();
        newPo.setOrderCode("SP-BJRK-" + DateUtil.format(date, "yyyyMMdd") + "-" + getPartCode("PART_IN_NUMBER"));
        newPo.setOrderType(0);
        newPo.setState(0);
        newPo.setOperationEmployeeId(li.getLoginEmployeeId());
        newPo.setOperationTime(date);
        newPo.setInOutType(inType);
        newPo.setApplyId(0L);
        newPo.setBusinessId(0L);
        newPo.setBusinessCode("");
        partOrderMapper.insert(newPo);

        Map<Long, Integer> partAddNumMap = new HashMap<>();
        for (Object obj : JSONUtil.parseArray(data)) {
            JSONObject jsonObj = JSONUtil.parseObj(obj);
            long stockId = jsonObj.getLong("stockId");
            int num = jsonObj.getInt("num");
            PartStock ps = partStockMapper.selectByPrimaryKey(stockId);
            ps.setStock(ps.getStock() + num);
            partStockMapper.updateByPrimaryKey(ps);
            PartOrderDetail newPod = new PartOrderDetail();
            newPod.setOrderId(newPo.getId());
            newPod.setPartId(ps.getPartId());
            newPod.setStockId(stockId);
            newPod.setOutApplyNum(0);
            newPod.setInOutNum(num);
            partOrderDetailMapper.insert(newPod);
            if (partAddNumMap.containsKey(ps.getPartId())) {
                partAddNumMap.put(ps.getPartId(), partAddNumMap.get(ps.getPartId()) + num);
            } else {
                partAddNumMap.put(ps.getPartId(), num);
            }
        }

        for (long partId : partAddNumMap.keySet()) {
            PartInfo pi = partInfoMapper.selectByPrimaryKey(partId);
            pi.setStock(pi.getStock() + partAddNumMap.get(partId));
            partInfoMapper.updateByPrimaryKeySelective(pi);
        }
        return DataResult.build9100();
    }

    @Override
    public DataResult selectPartApply(LoginInfo li, int pageNum, int pageSize, String applyCode, String state, String minPartClass, String maxPartClass, String minPassTime, String maxPassTime) throws Exception {
        Map<Integer, String> outTypeMap = commonService.getDictMap("TYPE_PART_OUT_TYPE");

        PartApplyExample paExample = new PartApplyExample();
        PartApplyExample.Criteria paCriteria = paExample.createCriteria();
        if (StrUtil.isNotBlank(applyCode)) {
            paCriteria.andApplyCodeLike("%" + applyCode + "%");
        }
        if (StrUtil.isNotBlank(state)) {
            paCriteria.andStateEqualTo(Integer.parseInt(state));
        }
        if (StrUtil.isNotBlank(minPartClass)) {
            paCriteria.andPartClassGreaterThanOrEqualTo(Integer.parseInt(minPartClass));
        }
        if (StrUtil.isNotBlank(maxPartClass)) {
            paCriteria.andPartClassLessThanOrEqualTo(Integer.parseInt(maxPartClass));
        }
        if (StrUtil.isNotBlank(minPassTime)) {
            paCriteria.andPassTimeGreaterThan(DateUtil.parseDate(minPassTime));
        }
        if (StrUtil.isNotBlank(maxPassTime)) {
            paCriteria.andPassTimeLessThanOrEqualTo(DateUtil.parseDate(maxPassTime));
        }
        paCriteria.andApplyEmployeeIdEqualTo(li.getLoginEmployeeId());
        paCriteria.andIsDeleteEqualTo(0);
        paExample.setOrderByClause("apply_time desc");
        Page<PartApply> page = PageHelper.startPage(pageNum, pageSize);
        List<PartApply> paList = partApplyMapper.selectByExample(paExample);
        List<Map<String, Object>> list = new ArrayList<>();
        for (PartApply pa : paList) {
            Map<String, Object> map = new HashMap<>();
            map.put("id", pa.getId());
            map.put("applyCode", pa.getApplyCode());
            map.put("outType", outTypeMap.get(pa.getOutType()));
            map.put("employeeName", SystemData.employeeMap.get(pa.getApplyEmployeeId()).getEmployeeName());
            map.put("applyTime", DateUtil.formatDateTime(pa.getApplyTime()));
            map.put("state", pa.getState());
            map.put("partClass", pa.getPartClass());
            map.put("partNum", pa.getPartNum());
            map.put("businessId", pa.getBusinessId());
            map.put("businessCode", pa.getBusinessCode());
            list.add(map);
        }
        return DataResult.build9100(new GridData(page.getTotal(), list));
    }

    @Override
    public DataResult selectPartApplyOne(LoginInfo li, long id) throws Exception {
        PartApply pa = partApplyMapper.selectByPrimaryKey(id);

        List<Map<String, Object>> partList = new ArrayList<>();
        PartApplyDetailExample padExample = new PartApplyDetailExample();
        padExample.createCriteria().andApplyIdEqualTo(pa.getId());
        List<PartApplyDetail> padList = partApplyDetailMapper.selectByExample(padExample);

        List<PartInnStock> partInnStocks = new ArrayList<>();
        List<Long> partIdList = padList.stream().map(PartApplyDetail::getPartId).collect(Collectors.toList());
        if (CollUtil.isNotEmpty(partIdList)) {
            partInnStocks = partInnStockMapper.selectByPartIdList(partIdList);
        }
        for (PartApplyDetail pad : padList) {
            PartInfo pi = partInfoMapper.selectByPrimaryKey(pad.getPartId());
            Map<String, Object> partMap = new HashMap<>();
            Integer stock = findPartInnStocks(partInnStocks, pi.getId());
            partMap.put("id", pad.getPartId());
            partMap.put("code", pi.getCode());
            partMap.put("name", pi.getName());
            partMap.put("brand", pi.getBrand());
            partMap.put("specs", pi.getSpecs());
            partMap.put("unit", pi.getUnit());
            partMap.put("stock", pi.getStock());
            partMap.put("useStock", (pi.getStock() + stock) - pi.getTransitStock());
            partMap.put("num", pad.getNum());
            partMap.put("price", pad.getPrice());
            partList.add(partMap);
        }

        Map<String, Object> map = new HashMap<>();
        map.put("id", pa.getId());
        map.put("applyCode", pa.getApplyCode());
        map.put("outType", pa.getOutType());
        map.put("employeeName", SystemData.employeeMap.get(pa.getApplyEmployeeId()).getEmployeeName());
        map.put("applyTime", DateUtil.formatDateTime(pa.getApplyTime()));
        map.put("applyDesc", pa.getApplyDesc());
        map.put("state", pa.getState());
        map.put("partClass", pa.getPartClass());
        map.put("partNum", pa.getPartNum());
        map.put("businessId", pa.getBusinessId());
        map.put("businessCode", pa.getBusinessCode());
        map.put("partList", partList);
        return DataResult.build9100(map);
    }

    @Override
    public DataResult insertPartApply(LoginInfo li, int outType, String applyDesc, String businessId, String businessCode, String data) throws Exception {
        int partNum = 0;
        Map<Long, Integer> partMap = new HashMap<>();
         ArrayList<Long> partIdList = CollUtil.newArrayList();
        for (Object obj : JSONUtil.parseArray(data)) {
            JSONObject jsonObj = JSONUtil.parseObj(obj);
            long partId = jsonObj.getLong("partId");
            partIdList.add(partId);
            int num = jsonObj.getInt("num");
            if (partMap.containsKey(partId)) {
                partMap.put(partId, partMap.get(partId) + num);
            } else {
                partMap.put(partId, num);
            }
            partNum += num;
        }
        Map<Long, PartInfo> partMapByPartIdList = getPartMapByPartIdList(partIdList);


        Date date = new Date();
        PartApply newPa = new PartApply();
        newPa.setApplyCode("SP-BJSQ-" + DateUtil.format(date, "yyyyMMdd") + "-" + getPartCode("PART_APPLY_NUMBER"));
        newPa.setOutType(outType);
        newPa.setState(0);
        newPa.setApplyEmployeeId(li.getLoginEmployeeId());
        newPa.setApplyTime(date);
        newPa.setApplyDesc(StrUtil.isBlank(applyDesc) ? "" : applyDesc);
        newPa.setPartClass(partMap.size());
        newPa.setPartNum(partNum);
        newPa.setIsDelete(0);
        if (StrUtil.isNotBlank(businessId)) {
            newPa.setBusinessId(Long.parseLong(businessId));
        } else {
            newPa.setBusinessId(0L);
        }
        if (StrUtil.isNotBlank(businessCode)) {
            newPa.setBusinessCode(businessCode);
        } else {
            newPa.setBusinessCode("");
        }
        newPa.setIsDelete(0);
        partApplyMapper.insert(newPa);

        for (long partId : partMap.keySet()) {
            PartApplyDetail newPad = new PartApplyDetail();
            newPad.setApplyId(newPa.getId());
            newPad.setId(newPa.getId());
            newPad.setPartId(partId);
            newPad.setNum(partMap.get(partId));
            Optional.ofNullable(partMapByPartIdList.get(partId)).ifPresent(item -> {
                newPad.setPrice(item.getPrice());
            });
            partApplyDetailMapper.insert(newPad);
        }

        insertPartApplyLog(newPa.getId(), li.getLoginEmployeeId(), date, 0, "");
        String outTypeStr = commonService.getDictMap("TYPE_PART_OUT_TYPE").get(outType);
        commonService.insertMessageBacklog(
                1L,
                "新增备件申请待审核，请处理",
                "用户【" + outTypeStr + "】申请备件，请审核申请信息。",
                5, 1, newPa.getId(), newPa.getApplyCode()
        );

        return DataResult.build9100(newPa.getId());
    }

    @Override
    public DataResult updatePartApply(LoginInfo li, long id, int outType, String applyDesc, String data) throws Exception {
        int partNum = 0;
        Map<Long, Integer> partMap = new HashMap<>();
        ArrayList<Long> partIdList = CollUtil.newArrayList();
        for (Object obj : JSONUtil.parseArray(data)) {
            JSONObject jsonObj = JSONUtil.parseObj(obj);
            long partId = jsonObj.getLong("partId");
            partIdList.add(partId);
            int num = jsonObj.getInt("num");
            if (partMap.containsKey(partId)) {
                partMap.put(partId, partMap.get(partId) + num);
            } else {
                partMap.put(partId, num);
            }
            partNum += num;
        }

        PartApply newPa = new PartApply();
        newPa.setId(id);
        newPa.setOutType(outType);
        newPa.setApplyDesc(StrUtil.isBlank(applyDesc) ? "" : applyDesc);
        newPa.setPartClass(partMap.size());
        newPa.setPartNum(partNum);
        partApplyMapper.updateByPrimaryKeySelective(newPa);


        Map<Long, PartInfo> partMapByPartIdList = getPartMapByPartIdList(partIdList);

        PartApplyDetailExample padExample = new PartApplyDetailExample();
        padExample.createCriteria().andApplyIdEqualTo(id);
        partApplyDetailMapper.deleteByExample(padExample);
        for (long partId : partMap.keySet()) {
            PartApplyDetail newPad = new PartApplyDetail();
            newPad.setApplyId(newPa.getId());
            newPad.setId(newPa.getId());
            newPad.setPartId(partId);
            newPad.setNum(partMap.get(partId));
            newPad.setPrice(BigDecimal.ZERO);
            Optional.ofNullable(partMapByPartIdList.get(partId)).ifPresent(item -> {
                newPad.setPrice(item.getPrice());
            });
            partApplyDetailMapper.insert(newPad);
        }

        return DataResult.build9100();
    }




    /**
     * 根据给定的备件ID列表获取对应的备件信息映射。
     *
     * @param partIdList 备件ID列表
     * @return 备件ID与备件信息的映射
     */
    @Override
    public Map<Long, PartInfo> getPartMapByPartIdList(List<Long> partIdList) {
        // 创建一个空的Map用于存储备件信息
        Map<Long, PartInfo> partMap = new HashMap<>();

        // 创建查询条件
        PartInfoExample partInfoExample = new PartInfoExample();
        partInfoExample.createCriteria().andIdIn(partIdList);

        // 执行查询获取备件信息列表
        List<PartInfo> partInfoList = partInfoMapper.selectByExample(partInfoExample);
        if(CollUtil.isEmpty(partInfoList)) {
            return partMap;
        }
        // 将查询结果转换为Map
        for (PartInfo partInfo : partInfoList) {
            partMap.put(partInfo.getId(), partInfo);
        }

        return partMap;
    }

    /**
     * 根据申请ID获取零件申请明细列表
     * @param applyId 申请ID
     * @return 零件申请明细列表
     */
    @Override
    public List<PartApplyDetail> getPartApplyDetailByApplyId(Long applyId){
        PartApplyDetailExample padExample = new PartApplyDetailExample();
        padExample.createCriteria().andApplyIdEqualTo(applyId);
        return partApplyDetailMapper.selectByExample(padExample);
    }


    /**
     * 更新备件申请状态
     * @param li 登录信息
     * @param id 备件申请ID
     * @param operation 操作类型：1提交，2审批通过，3审批驳回，5删除
     * @param applyDesc 审批描述
     * @return DataResult
     * @throws Exception
     */
    @Override
    public DataResult updatePartApplyState(LoginInfo li, long id, int operation, String applyDesc) throws Exception {
        // 申请状态：0未发起，1审批中，2审批通过，3审批驳回，4已出库
        // operation：1提交，2审批通过，3审批驳回，5删除

        PartApply pa = partApplyMapper.selectByPrimaryKey(id);
        if(pa == null){
            return DataResult.build9404();
        }


        switch (operation) {
            case OP_INIT_APPROVAL:
                // 提交
                return initApproval(pa,li,applyDesc);
            case OP_OUT_OF_STOCK:
            case OP_DEPARTMENT_APPROVAL:
                // 系长审批 / 出库
                return outOfStock(pa,li,applyDesc);
            case OP_REJECTED:
                // 驳回
                return rejected(pa,li,applyDesc);
            case OP_DELETE_PARTAPPLY:
                // 删除
                return deletePartApply(pa,li);
            case OP_LEADER_APPROVAL:
                // 班长审批
                return leaderApproval(pa,li,applyDesc);
            case OP_WAREHOUSE_APPROVAL:
                // 仓库管理员审核
                return warehouseApproval(pa,li,applyDesc);
        }
        return DataResult.build9100();
    }


    /**
     * 处理备件申请被驳回的逻辑，更新备件库存和状态，发送消息通知。
     * @param pa 备件申请对象
     * @param li 登录信息对象
     * @return 处理结果
     * @throws Exception 可能抛出的异常
     */
    private DataResult rejected(PartApply pa,LoginInfo li,String applyDesc) throws Exception {
        List<PartApplyDetail> padList = getPartApplyDetailByApplyId(pa.getId());
        List<Long> partIdList = padList.stream().map(PartApplyDetail::getPartId).collect(Collectors.toList());
        Map<Long, PartInfo> partMap = getPartMapByPartIdList(partIdList);
        for (PartApplyDetail pad : padList) {
            PartInfo pi = partMap.get(pad.getPartId());
            PartInfo newPi = new PartInfo();
            newPi.setId(pi.getId());
            newPi.setTransitStock(NumberUtil.max(pi.getTransitStock() - pad.getNum(), 0));
            partInfoMapper.updateByPrimaryKeySelective(newPi);
        }
        pa.setState(PartApplyStateEnum.REJECTED.getStatus());
        partApplyMapper.updateByPrimaryKeySelective(pa);

        if(StrUtil.isBlank(applyDesc)) {
            applyDesc="驳回";
        }
        PartApplyLog partApplyLog = new PartApplyLog();
        partApplyLog.setApplyId(pa.getId());
        partApplyLog.setOperationTime(new Date());
        partApplyLog.setOperationDesc(applyDesc);

        partApplyLog.setOperation(3);
        partApplyLog.setEmployeeId(li.getLoginEmployeeId());
        partApplyLogMapper.insert(partApplyLog);
        commonService.insertMessageInform(
                pa.getApplyEmployeeId(),
                "备件申请审核驳回，请知悉",
                "备件申请单【" + pa.getApplyCode() + "】备件申请已通过，请到仓库进行备件领取出库。",
                5, 3, pa.getId(), pa.getApplyCode()
        );
        return DataResult.build9100();
    }

    /**
     * 提交
     * @param pa 零件申请单对象
     * @param li 登录信息对象
     * @return 审批结果
     */
    private DataResult initApproval(PartApply pa,LoginInfo li,String applyDesc) {
        if (!PartApplyStateEnum.INIT.getStatus().equals(pa.getState()) && !PartApplyStateEnum.REJECTED.getStatus().equals(pa.getState())) {
            return DataResult.build9250("审批中、审批通过、已出库的申请单无法提交");
        }

        List<PartApplyDetail> padList = getPartApplyDetailByApplyId(pa.getId());
        List<Long> partIdList = padList.stream().map(PartApplyDetail::getPartId).collect(Collectors.toList());
        Map<Long, PartInnStock> partInnStockMap = partInnStockService.getPartInnStockByPartIdList(partIdList);
        Map<Long, PartInfo> partMap = getPartMapByPartIdList(partIdList);
        for (PartApplyDetail pad : padList) {
            PartInfo pi = partMap.get(pad.getPartId());
            Integer innStock = 0;
            PartInnStock partInnStock = partInnStockMap.get(pad.getPartId());
            if(partInnStock != null && partInnStock.getStock() > 0){
                innStock = partInnStock.getStock();
            }
            // 外库库存不足
            if (pi == null || pad.getNum() > (innStock + pi.getStock()) - pi.getTransitStock()) {
                return DataResult.build9250("库存不足");
            }
        }
        for (PartApplyDetail pad : padList) {
            PartInfo pi = partMap.get(pad.getPartId());
            PartInfo newPi = new PartInfo();
            newPi.setId(pi.getId());
            newPi.setTransitStock(pi.getTransitStock() + pad.getNum());
            partInfoMapper.updateByPrimaryKeySelective(newPi);
        }
        pa.setState(PartApplyStateEnum.LEADER_APPROVAL.getStatus());
        partApplyMapper.updateByPrimaryKeySelective(pa);
        if(StrUtil.isBlank(applyDesc)) {
            applyDesc="提交成功";
        }
        PartApplyLog partApplyLog = new PartApplyLog();
        partApplyLog.setApplyId(pa.getId());
        partApplyLog.setOperationTime(new Date());
        partApplyLog.setOperationDesc(applyDesc);
        // 操作：0创建，1班长审批，2审批通过，3审批驳回，4出库，5删除 10仓库管理员审批  20系长审批
        partApplyLog.setOperation(1);
        partApplyLog.setEmployeeId(li.getLoginEmployeeId());
        partApplyLogMapper.insert(partApplyLog);
        return DataResult.build9100();
    }

    /**
     * 班长审批
     * @param pa 申请单信息
     * @param li 登录用户信息
     * @return 审批结果
     */
    private DataResult leaderApproval(PartApply pa,LoginInfo li,String applyDesc){
        if (!PartApplyStateEnum.LEADER_APPROVAL.getStatus().equals(pa.getState())) {
            return DataResult.build9250("状态错误");
        }
        pa.setState(PartApplyStateEnum.WAREHOUSE_APPROVAL.getStatus());
        partApplyMapper.updateByPrimaryKeySelective(pa);
        if(StrUtil.isBlank(applyDesc)) {
            applyDesc="班长审批成功";
        }
        PartApplyLog partApplyLog = new PartApplyLog();
        partApplyLog.setApplyId(pa.getId());
        partApplyLog.setOperationTime(new Date());
        partApplyLog.setOperationDesc(applyDesc);

        partApplyLog.setOperation(10);
        partApplyLog.setEmployeeId(li.getLoginEmployeeId());
        partApplyLogMapper.insert(partApplyLog);
        return DataResult.build9100();
    }


    /**
     * 执行仓库审批操作。
     * @param pa PartApply对象，包含零件申请的详细信息。
     * @param li LoginInfo对象，包含当前登录用户的信息。
     * @return DataResult对象，表示操作结果。
     */
    private DataResult warehouseApproval(PartApply pa,LoginInfo li,String applyDesc) throws Exception{
        if (!PartApplyStateEnum.WAREHOUSE_APPROVAL.getStatus().equals(pa.getState())) {
            return DataResult.build9250("状态错误");
        }
        pa.setState(PartApplyStateEnum.APPROVED.getStatus());
        List<PartApplyDetail> padList = getPartApplyDetailByApplyId(pa.getId());
        for(PartApplyDetail partApplyDetail : padList){
            if(partApplyDetail.getPrice().compareTo(new BigDecimal(MAX_PRICE)) >= 0){
                pa.setState(PartApplyStateEnum.DEPARTMENT_APPROVAL.getStatus());
                partApplyMapper.updateByPrimaryKeySelective(pa);
                if(StrUtil.isBlank(applyDesc)) {
                    applyDesc="仓库管理员审批成功";
                }
                PartApplyLog partApplyLog = new PartApplyLog();
                partApplyLog.setApplyId(pa.getId());
                partApplyLog.setOperationTime(new Date());
                partApplyLog.setOperationDesc(applyDesc);

                partApplyLog.setOperation(20);
                partApplyLog.setEmployeeId(li.getLoginEmployeeId());
                partApplyLogMapper.insert(partApplyLog);
                return DataResult.build9100();
            }
        }
        return outOfStock(pa,li,applyDesc);
    }

    /**
     * 处理备件申请出库操作，生成相应的备件订单和订单详情，并更新备件申请状态。
     * @param pa 备件申请对象
     * @param li 登录信息对象
     * @return 处理结果
     * @throws Exception 异常信息
     */
    private DataResult outOfStock(PartApply pa,LoginInfo li,String applyDesc) throws Exception {

        List<PartApplyDetail> padList = getPartApplyDetailByApplyId(pa.getId());
        PartOrder newPo = new PartOrder();
        newPo.setOrderCode("SP-BJCK-" + DateUtil.format(new Date(), "yyyyMMdd") + "-" + getPartCode("PART_OUT_NUMBER"));
        newPo.setOrderType(1);
        newPo.setState(1);
        newPo.setOperationEmployeeId(pa.getApplyEmployeeId());
        newPo.setOperationTime(new Date());
        newPo.setInOutType(pa.getOutType());
        newPo.setApplyId(pa.getId());
        newPo.setBusinessId(pa.getBusinessId());
        newPo.setBusinessCode(pa.getBusinessCode());

        List<PartOrderDetail> partOrderDetailList = new ArrayList<>();
        Map<Long,Integer> partNumMap = new HashMap<>();
        for (PartApplyDetail pad : padList) {
            int needPartNum = pad.getNum();

            List<PartStock> psList = getPartStockListByPartId(pad.getPartId());
            if (psList == null || psList.isEmpty()) {
                return DataResult.build9250("审批通过失败，无可用备件");
            }
            for (PartStock ps : psList) {
                if (needPartNum <= 0) {
                    break;
                }
                int partNum = ps.getStock();


                if (needPartNum < ps.getStock()) {
                    partNum = needPartNum;
                }
                needPartNum -= ps.getStock();

                PartOrderDetail newPod = new PartOrderDetail();

                newPod.setPartId(ps.getPartId());
                newPod.setStockId(ps.getId());
                newPod.setOutApplyNum(partNum);
                newPod.setInOutNum(0);
                if(partNum > 0){
                    partOrderDetailList.add(newPod);
                }
                //partOrderDetailMapper.insert(newPod);

            }
            if(needPartNum > 0){
                // 剩下的从内库 出库
                partNumMap.put(pad.getPartId(),needPartNum);
            }
        }
        pa.setState(PartApplyStateEnum.APPROVED.getStatus());
        pa.setPassTime(new Date());
        partApplyMapper.updateByPrimaryKeySelective(pa);

        if(!partOrderDetailList.isEmpty()) {
            partOrderMapper.insert(newPo);
            for(PartOrderDetail partOrderDetail : partOrderDetailList){
                partOrderDetail.setOrderId(newPo.getId());
                partOrderDetailMapper.insert(partOrderDetail);
            }
        }
        createOutInnerStockBill(partNumMap,newPo,li);
        commonService.insertMessageInform(
                pa.getApplyEmployeeId(),
                "备件申请审核通过，请知悉",
                "备件申请单【" + pa.getApplyCode() + "】备件申请已通过，请到仓库进行备件领取出库。",
                5, 2, pa.getId(), pa.getApplyCode()
        );

        if(StrUtil.isBlank(applyDesc)) {
            applyDesc="审批通过";
        }
        PartApplyLog partApplyLog = new PartApplyLog();
        partApplyLog.setApplyId(pa.getId());
        partApplyLog.setOperationTime(new Date());
        partApplyLog.setOperationDesc(applyDesc);

        partApplyLog.setOperation(2);
        partApplyLog.setEmployeeId(li.getLoginEmployeeId());
        partApplyLogMapper.insert(partApplyLog);
        return DataResult.build9100();
    }

    private Long createOutInnerStockBill(Map<Long,Integer> partNumMap,PartOrder partOrder,LoginInfo li) throws Exception{
        if(partNumMap == null || partNumMap.isEmpty() || partOrder == null){
            return 0L;
        }
        List<Long> partIdList = new ArrayList<>(partNumMap.keySet());
        Map<Long, PartInnStock> partInnStockMap = partInnStockService.getPartInnStockByPartIdList(partIdList);
        PartInnOrder partInnOrder = new PartInnOrder();
        partInnOrder.setInnOrderCode("SP-INN_BJCK-" + DateUtil.format(new Date(), "yyyyMMdd") + "-" + getPartCode("PART_INN_OUT_ORDER"));
        partInnOrder.setInnOrderType(1);
        partInnOrder.setOperationEmployeeId(li.getLoginEmployeeId());
        partInnOrder.setOperationTime(new Date());
        partInnOrder.setInOutType(1);
        partInnOrder.setApplyId(partOrder.getApplyId());
        partInnOrder.setBusinessId(partOrder.getBusinessId());
        partInnOrder.setBusinessCode(partOrder.getBusinessCode());
        partInnOrderMapper.insert(partInnOrder);

        partNumMap.forEach((key, value) -> {
            PartInnStock partInnStock = partInnStockMap.get(key);
            if (partInnStock == null) {
                partInnStock = new PartInnStock();
                partInnStock.setPartId(key);
                partInnStock.setStock(value * -1);
                partInnStock.setIsDelete(0);
                partInnStockMapper.insert(partInnStock);
            } else {
                partInnStock.setStock(partInnStock.getStock() - value);
                partInnStockMapper.updateStockByPk(partInnStock);
            }
            PartInnOrderDetail partInnOrderDetail = new PartInnOrderDetail();
            partInnOrderDetail.setPartId(key);
            partInnOrderDetail.setInnOrderId(partInnOrder.getId());
            partInnOrderDetail.setInOutNum(value * -1);
            partInnOrderDetailMapper.insert(partInnOrderDetail);
        });
        return partInnOrder.getId();
    }



    private List<PartStock> getPartStockListByPartId(Long partId){
        PartStockExample psExample = new PartStockExample();
        PartStockExample.Criteria psCriteria = psExample.createCriteria();
        psCriteria.andPartIdEqualTo(partId);
        //psCriteria.andStockGreaterThan(0);
        psExample.setOrderByClause("stock desc");
        return partStockMapper.selectByExample(psExample);
    }

    /**
     * 删除零件申请单。
     * @param pa 零件申请单对象。
     * @param li 登录信息对象。
     * @return 操作结果。
     */
    private DataResult deletePartApply(PartApply pa,LoginInfo li){
        if (!PartApplyStateEnum.INIT.getStatus().equals(pa.getState()) && !PartApplyStateEnum.REJECTED.getStatus().equals(pa.getState())) {
            return DataResult.build9250("审批中、审批通过、已出库的申请单无法提交");
        }
        pa.setIsDelete(1);
        partApplyMapper.updateByPrimaryKeySelective(pa);
        return DataResult.build9100();
    }

    @Override
    public DataResult selectPartApplyLog(LoginInfo li, int pageNum, int pageSize, long id) throws Exception {
        PartApplyLogExample palExample = new PartApplyLogExample();
        palExample.createCriteria().andApplyIdEqualTo(id);
        palExample.setOrderByClause("operation_time desc");
        Page<PartApplyLog> page = PageHelper.startPage(pageNum, pageSize);
        List<PartApplyLog> palList = partApplyLogMapper.selectByExample(palExample);
        List<Map<String, Object>> list = new ArrayList<>();
        for (PartApplyLog pal : palList) {
            Map<String, Object> map = new HashMap<>();
            map.put("operation", pal.getOperation());
            map.put("employeeName", SystemData.employeeMap.get(pal.getEmployeeId()).getEmployeeName());
            map.put("operationTime", DateUtil.formatDateTime(pal.getOperationTime()));
            map.put("operationDesc", pal.getOperationDesc());
            list.add(map);
        }
        return DataResult.build9100(new GridData(page.getTotal(), list));
    }

    @Override
    public DataResult selectPartReview(LoginInfo li, int pageNum, int pageSize, String applyCode, String state) throws Exception {
        Map<Integer, String> outTypeMap = commonService.getDictMap("TYPE_PART_OUT_TYPE");

        PartApplyExample paExample = new PartApplyExample();
        PartApplyExample.Criteria paCriteria = paExample.createCriteria();
        if (StrUtil.isNotBlank(applyCode)) {
            paCriteria.andApplyCodeLike("%" + applyCode + "%");
        }
        if (StrUtil.isNotBlank(state)) {
            paCriteria.andStateEqualTo(Integer.parseInt(state));
        } else {
            paCriteria.andStateIn(Arrays.asList(1, 2));
        }
        paCriteria.andIsDeleteEqualTo(0);
        paExample.setOrderByClause("apply_time desc");
        Page<PartApply> page = PageHelper.startPage(pageNum, pageSize);
        List<PartApply> paList = partApplyMapper.selectByExample(paExample);
        List<Map<String, Object>> list = new ArrayList<>();
        for (PartApply pa : paList) {
            Map<String, Object> map = new HashMap<>();
            map.put("id", pa.getId());
            map.put("applyCode", pa.getApplyCode());
            map.put("outType", outTypeMap.get(pa.getOutType()));
            map.put("employeeName", SystemData.employeeMap.get(pa.getApplyEmployeeId()).getEmployeeName());
            map.put("applyTime", DateUtil.formatDateTime(pa.getApplyTime()));
            map.put("state", pa.getState());
            map.put("partClass", pa.getPartClass());
            map.put("partNum", pa.getPartNum());
            list.add(map);
        }
        return DataResult.build9100(new GridData(page.getTotal(), list));
    }

    @Override
    public DataResult selectPartOrder(LoginInfo li, int pageNum, int pageSize, String orderCode, String operationEmployeeName, String businessCode, String orderType, String minOperationTime, String maxOperationTime, String inOutType, String state) throws Exception {
        Map<Integer, String> typeMap = commonService.getDictMap("TYPE_PART_IN_TYPE", "TYPE_PART_OUT_TYPE");

        PartOrderExample poExample = new PartOrderExample();
        PartOrderExample.Criteria poCriteria = poExample.createCriteria();
        if (StrUtil.isNotBlank(orderCode)) {
            poCriteria.andOrderCodeLike("%" + orderCode + "%");
        }
        if (StrUtil.isNotBlank(operationEmployeeName)) {
            SystemEmployeeExample seExample = new SystemEmployeeExample();
            seExample.createCriteria().andEmployeeNameLike("%" + operationEmployeeName + "%").andIsDeleteEqualTo(0);
            List<SystemEmployee> seList = systemEmployeeMapper.selectByExample(seExample);
            List<Long> employeeIdList = new ArrayList<>();
            for (SystemEmployee se : seList) {
                employeeIdList.add(se.getId());
            }
            if (employeeIdList.size() > 0) {
                poCriteria.andOperationEmployeeIdIn(employeeIdList);
            }
        }
        if (StrUtil.isNotBlank(businessCode)) {
            poCriteria.andBusinessCodeLike("%" + businessCode + "%");
        }
        if (StrUtil.isNotBlank(orderType)) {
            poCriteria.andOrderTypeEqualTo(Integer.parseInt(orderType));
        }
        if (StrUtil.isNotBlank(minOperationTime)) {
            poCriteria.andOperationTimeGreaterThanOrEqualTo(DateUtil.parseDate(minOperationTime));
        }
        if (StrUtil.isNotBlank(maxOperationTime)) {
            poCriteria.andOperationTimeLessThanOrEqualTo(DateUtil.parseDate(maxOperationTime));
        }
        if (StrUtil.isNotBlank(inOutType)) {
            poCriteria.andInOutTypeEqualTo(Integer.parseInt(inOutType));
        }
        if (StrUtil.isNotBlank(state)) {
            poCriteria.andStateEqualTo(Integer.parseInt(state));
        }
        poExample.setOrderByClause("operation_time desc");
        Page<PartOrder> page = PageHelper.startPage(pageNum, pageSize);
        List<PartOrder> poList = partOrderMapper.selectByExample(poExample);
        List<Map<String, Object>> list = new ArrayList<>();
        for (PartOrder po : poList) {
            PartOrderDetailExample podExample = new PartOrderDetailExample();
            podExample.createCriteria().andOrderIdEqualTo(po.getId());
            long partNum = partOrderDetailMapper.countByExample(podExample);
            Map<String, Object> map = new HashMap<>();
            map.put("id", po.getId());
            map.put("orderCode", po.getOrderCode());
            map.put("orderType", po.getOrderType());
            map.put("state", po.getState());
            map.put("operationEmployeeName", SystemData.employeeMap.get(po.getOperationEmployeeId()).getEmployeeName());
            map.put("operationTime", DateUtil.formatDateTime(po.getOperationTime()));
            map.put("inOutType", typeMap.get(po.getInOutType()));
            map.put("businessCode", po.getBusinessCode());
            map.put("partNum", partNum);
            list.add(map);
        }
        return DataResult.build9100(new GridData(page.getTotal(), list));
    }




    @Override
    public DataResult selectPartOrderByUserId(LoginInfo li, int pageNum, int pageSize, String orderCode, String operationEmployeeName, String businessCode, String orderType, String minOperationTime, String maxOperationTime, String inOutType, String state) throws Exception {
        Map<Integer, String> typeMap = commonService.getDictMap("TYPE_PART_IN_TYPE", "TYPE_PART_OUT_TYPE");

        PartOrderExample poExample = new PartOrderExample();
        PartOrderExample.Criteria poCriteria = poExample.createCriteria();
        poCriteria.andOperationEmployeeIdEqualTo(li.getLoginEmployeeId());
        if (StrUtil.isNotBlank(orderCode)) {
            poCriteria.andOrderCodeLike("%" + orderCode + "%");
        }
        if (StrUtil.isNotBlank(operationEmployeeName)) {
            SystemEmployeeExample seExample = new SystemEmployeeExample();
            seExample.createCriteria().andEmployeeNameLike("%" + operationEmployeeName + "%").andIsDeleteEqualTo(0);
            List<SystemEmployee> seList = systemEmployeeMapper.selectByExample(seExample);
            List<Long> employeeIdList = new ArrayList<>();
            for (SystemEmployee se : seList) {
                employeeIdList.add(se.getId());
            }
            if (employeeIdList.size() > 0) {
                poCriteria.andOperationEmployeeIdIn(employeeIdList);
            }
        }
        if (StrUtil.isNotBlank(businessCode)) {
            poCriteria.andBusinessCodeLike("%" + businessCode + "%");
        }
        if (StrUtil.isNotBlank(orderType)) {
            poCriteria.andOrderTypeEqualTo(Integer.parseInt(orderType));
        }
        if (StrUtil.isNotBlank(minOperationTime)) {
            poCriteria.andOperationTimeGreaterThanOrEqualTo(DateUtil.parseDate(minOperationTime));
        }
        if (StrUtil.isNotBlank(maxOperationTime)) {
            poCriteria.andOperationTimeLessThanOrEqualTo(DateUtil.parseDate(maxOperationTime));
        }
        if (StrUtil.isNotBlank(inOutType)) {
            poCriteria.andInOutTypeEqualTo(Integer.parseInt(inOutType));
        }
        if (StrUtil.isNotBlank(state)) {
            poCriteria.andStateEqualTo(Integer.parseInt(state));
        }
        poExample.setOrderByClause("operation_time desc");
        Page<PartOrder> page = PageHelper.startPage(pageNum, pageSize);
        List<PartOrder> poList = partOrderMapper.selectByExample(poExample);
        List<Map<String, Object>> list = new ArrayList<>();
        for (PartOrder po : poList) {
            PartOrderDetailExample podExample = new PartOrderDetailExample();
            podExample.createCriteria().andOrderIdEqualTo(po.getId());
            long partNum = partOrderDetailMapper.countByExample(podExample);
            Map<String, Object> map = new HashMap<>();
            map.put("id", po.getId());
            map.put("orderCode", po.getOrderCode());
            map.put("orderType", po.getOrderType());
            map.put("state", po.getState());
            map.put("operationEmployeeName", SystemData.employeeMap.get(po.getOperationEmployeeId()).getEmployeeName());
            map.put("operationTime", DateUtil.formatDateTime(po.getOperationTime()));
            map.put("inOutType", typeMap.get(po.getInOutType()));
            map.put("businessCode", po.getBusinessCode());
            map.put("partNum", partNum);
            list.add(map);
        }
        return DataResult.build9100(new GridData(page.getTotal(), list));
    }

    @Override
    public DataResult selectPartOrderOne(LoginInfo li, int orderType, long id) throws Exception {
        PartOrder po = partOrderMapper.selectByPrimaryKey(id);
        if (po == null || po.getOrderType() != orderType) {
            return DataResult.build9250("找不到该单据");
        }

        Map<Integer, String> typeMap = commonService.getDictMap("TYPE_PART_IN_TYPE", "TYPE_PART_OUT_TYPE");
        Map<Long, String> warehouseMap = new HashMap<>();
        List<PartWarehouse> pwList = partWarehouseMapper.selectByExample(null);
        for (PartWarehouse pw : pwList) {
            warehouseMap.put(pw.getId(), pw.getName());
        }

        List<Map<String, Object>> partList = new ArrayList<>();
        PartOrderDetailExample podExample = new PartOrderDetailExample();
        podExample.createCriteria().andOrderIdEqualTo(id);
        List<PartOrderDetail> podList = partOrderDetailMapper.selectByExample(podExample);

        List<PartInnStock> partInnStocks = new ArrayList<>();
        List<Long> partIdList = podList.stream().map(PartOrderDetail::getPartId).collect(Collectors.toList());
        if (CollUtil.isNotEmpty(partIdList)) {
            partInnStocks = partInnStockMapper.selectByPartIdList(partIdList);
        }
        for (PartOrderDetail pod : podList) {
            PartInfo pi = partInfoMapper.selectByPrimaryKey(pod.getPartId());
            PartStock ps = partStockMapper.selectByPrimaryKey(pod.getStockId());
            Integer stock = this.findPartInnStocks(partInnStocks,pod.getPartId());
            Map<String, Object> partMap = new HashMap<>();
            partMap.put("id", pi.getId());
            partMap.put("code", pi.getCode());
            partMap.put("name", pi.getName());
            partMap.put("brand", pi.getBrand());
            partMap.put("specs", pi.getSpecs());
            partMap.put("unit", pi.getUnit());
            partMap.put("stock", pi.getStock());
            partMap.put("useStock", (pi.getStock() + stock) - pi.getTransitStock());
            partMap.put("stockId", pod.getStockId());
            partMap.put("warehouse", warehouseMap.get(ps.getWarehouse()));
            partMap.put("locator", warehouseMap.get(ps.getLocator()));
            partMap.put("outApplyNum", pod.getOutApplyNum());
            partMap.put("num", Math.abs(pod.getInOutNum()));
            partList.add(partMap);
        }

        List<String> fileCodeList = new ArrayList<>();
        BusinessFileExample bfExample = new BusinessFileExample();
        bfExample.createCriteria().andBusTablesIdEqualTo(po.getId()).andBusTypeEqualTo(6).andFileGroupEqualTo(1).andFileTypeEqualTo(1);
        List<BusinessFile> bfList = businessFileMapper.selectByExample(bfExample);
        for (BusinessFile bf : bfList) {
            fileCodeList.add(bf.getFileCode());
        }
        PartApply pa = partApplyMapper.selectByPrimaryKey(po.getApplyId());
        Map<String, Object> map = new HashMap<>();
        map.put("id", po.getId());
        map.put("orderCode", po.getOrderCode());
        map.put("orderType", po.getOrderType());
        map.put("state", po.getState());
        map.put("operationEmployeeName", SystemData.employeeMap.get(po.getOperationEmployeeId()).getEmployeeName());
        map.put("operationTime", DateUtil.formatDateTime(po.getOperationTime()));
        map.put("inOutType", typeMap.get(po.getInOutType()));
        map.put("applyCode", pa == null ? "" : pa.getApplyCode());
        map.put("partList", partList);
        map.put("fileCodes", fileCodeList);
        return DataResult.build9100(map);
    }

    @Override
    public DataResult insertPartOut(LoginInfo li, long id, String data, String fileCodes) throws Exception {
        PartOrder po = partOrderMapper.selectByPrimaryKey(id);
        if (po == null || po.getOrderType() != 1) {
            return DataResult.build9250("找不到该单据");
        }
        if (po.getState() == 0) {
            return DataResult.build9250("已完成的备件出库单无法出库");
        }

        Map<Long, Integer> stockSubNumMap = new HashMap<>();
        Map<Long, Integer> partSubNumMap = new HashMap<>();
        for (Object obj : JSONUtil.parseArray(data)) {
            JSONObject jsonObj = JSONUtil.parseObj(obj);
            long partId = jsonObj.getLong("partId");
            long stockId = jsonObj.getLong("stockId");
            int num = jsonObj.getInt("num");
            stockSubNumMap.put(stockId, num);
            if (partSubNumMap.containsKey(partId)) {
                partSubNumMap.put(partId, partSubNumMap.get(partId) + num);
            } else {
                partSubNumMap.put(partId, num);
            }
        }

        Set<Long> partIdSet = new HashSet<>();
        Set<Long> stockIdSet = new HashSet<>();
        PartOrderDetailExample podExample = new PartOrderDetailExample();
        podExample.createCriteria().andOrderIdEqualTo(id);
        List<PartOrderDetail> podList = partOrderDetailMapper.selectByExample(podExample);
        for (PartOrderDetail pod : podList) {
            // 单个备件库存出库验证
            if (!partSubNumMap.containsKey(pod.getPartId())) {
                return DataResult.build9250("出库失败，找不到备件数据");
            }
            if (!stockSubNumMap.containsKey(pod.getStockId())) {
                return DataResult.build9250("出库失败，找不到备件库存数据");
            }
            int num = stockSubNumMap.get(pod.getStockId());
            if (pod.getOutApplyNum() + pod.getInOutNum() < num) {
                return DataResult.build9250("出库失败，出库的备件数量大于申请的备件数量");
            }
            PartStock ps = partStockMapper.selectByPrimaryKey(pod.getStockId());
            if (isPartInventory(ps.getWarehouse())) {
                return DataResult.build9250("出库失败，仓库正在盘点中，无法入库");
            }
            if (ps.getStock() < num) {
                return DataResult.build9250("出库失败，备件实际库存不足");
            }
            partIdSet.add(pod.getPartId());
            stockIdSet.add(pod.getStockId());
        }

        if (!(partIdSet.equals(partSubNumMap.keySet()) && stockIdSet.equals(stockSubNumMap.keySet()))) {
            return DataResult.build9250("出库失败，备件库存数据错误");
        }

        boolean isAllOut = true;
        for (PartOrderDetail pod : podList) {
            PartStock ps = partStockMapper.selectByPrimaryKey(pod.getStockId());
            // 单个备件库存出库验证，更新出库单详情
            int num = stockSubNumMap.get(pod.getStockId());
            pod.setInOutNum(pod.getInOutNum() - num);
            if (pod.getOutApplyNum() + pod.getInOutNum() > 0) {
                isAllOut = false;
            }
            if (num == 0) {
                break;
            }
            partOrderDetailMapper.updateByPrimaryKeySelective(pod);
            // 更新库存
            ps.setStock(ps.getStock() - num);
            partStockMapper.updateByPrimaryKeySelective(ps);
        }

        // 更新出库单
        Date date = new Date();
        if (isAllOut) {
            po.setState(0);
            // 更新申请单
            if (po.getApplyId() != 0L) {
                PartApply pa = partApplyMapper.selectByPrimaryKey(po.getApplyId());
                pa.setState(4);
                partApplyMapper.updateByPrimaryKeySelective(pa);
            }
            // 申请单日志
            insertPartApplyLog(id, li.getLoginEmployeeId(), date, 4, "");
        } else {
            po.setState(2);
        }
        partOrderMapper.updateByPrimaryKeySelective(po);

        // 保存图片
        BusinessFileExample bfExample = new BusinessFileExample();
        bfExample.createCriteria().andBusTablesIdEqualTo(po.getId()).andBusTypeEqualTo(6);
        businessFileMapper.deleteByExample(bfExample);
        for (String fileCode : fileCodes.split(",")) {
            BusinessFile newBf = new BusinessFile();
            newBf.setBusTablesId(po.getId());
            newBf.setBusType(6);
            newBf.setFileGroup(1);
            newBf.setFileCode(fileCode);
            newBf.setFileType(1);
            newBf.setEmployeeId(li.getLoginEmployeeId());
            newBf.setUpdateTime(date);
            newBf.setCreateTime(date);
            businessFileMapper.insert(newBf);
        }

        // 更新备件数据
        for (long partId : partSubNumMap.keySet()) {
            PartInfo pi = partInfoMapper.selectByPrimaryKey(partId);
            pi.setStock(pi.getStock() - partSubNumMap.get(partId));
            pi.setTransitStock(pi.getTransitStock() - partSubNumMap.get(partId));
            partInfoMapper.updateByPrimaryKeySelective(pi);
        }
        return DataResult.build9100();
    }

    @Override
    public DataResult selectPartWarehouseStock(LoginInfo li, int pageNum, int pageSize, String warehouse, String codeOrName) throws Exception {
        Map<Long, String> warehouseMap = new HashMap<>();
        List<PartWarehouse> pwList = partWarehouseMapper.selectByExample(null);
        for (PartWarehouse pw : pwList) {
            warehouseMap.put(pw.getId(), pw.getName());
        }

        PartStockExample psExample = new PartStockExample();
        PartStockExample.Criteria psCriteria = psExample.createCriteria();
        if (StrUtil.isNotBlank(codeOrName)) {
            PartInfoExample piExample = new PartInfoExample();
            PartInfoExample.Criteria piCriteria1 = piExample.createCriteria();
            PartInfoExample.Criteria piCriteria2 = piExample.or();
            piCriteria1.andCodeLike("%" + codeOrName + "%");
            piCriteria2.andNameLike("%" + codeOrName + "%");
            piCriteria1.andIsDeleteEqualTo(0);
            piCriteria2.andIsDeleteEqualTo(0);
            piExample.setOrderByClause("update_time desc");
            List<PartInfo> piList = partInfoMapper.selectByExample(piExample);
            List<Long> partIdList = new ArrayList<>();
            for (PartInfo pi : piList) {
                partIdList.add(pi.getId());
            }
            partIdList.add(0L);
            psCriteria.andPartIdIn(partIdList);
        }
        if (StrUtil.isNotBlank(warehouse)) {
            psCriteria.andWarehouseEqualTo(Long.parseLong(warehouse));
        }
        Page<PartInfo> page = PageHelper.startPage(pageNum, pageSize);
        List<PartStock> psList = partStockMapper.selectByExample(psExample);

        List<Map<String, Object>> list = new ArrayList<>();
        for (PartStock ps : psList) {
            PartInfo pi = partInfoMapper.selectByPrimaryKey(ps.getPartId());
            Map<String, Object> map = new HashMap<>();
            map.put("id", ps.getPartId());
            map.put("code", pi.getCode());
            map.put("name", pi.getName());
            map.put("specs", pi.getSpecs());
            map.put("brand", pi.getBrand());
            map.put("unit", pi.getUnit());
            map.put("price", pi.getPrice().toPlainString());
            map.put("stockId", ps.getId());
            map.put("warehouse", warehouseMap.get(ps.getWarehouse()));
            map.put("locator", warehouseMap.get(ps.getLocator()));
            map.put("stock", ps.getStock());
            list.add(map);
        }
        return DataResult.build9100(new GridData(page.getTotal(), list));
    }

    @Override
    public DataResult selectPartInventory(LoginInfo li, int pageNum, int pageSize, String inventoryCode, String state, String result) throws Exception {
        Map<Long, String> warehouseMap = new HashMap<>();
        List<PartWarehouse> pwList = partWarehouseMapper.selectByExample(null);
        for (PartWarehouse pw : pwList) {
            warehouseMap.put(pw.getId(), pw.getName());
        }

        PartInventoryExample piExample = new PartInventoryExample();
        PartInventoryExample.Criteria piCriteria = piExample.createCriteria();
        if (StrUtil.isNotBlank(inventoryCode)) {
            piCriteria.andInventoryCodeLike("%" + inventoryCode + "%");
        }
        if (StrUtil.isNotBlank(state)) {
            piCriteria.andStateEqualTo(Integer.parseInt(state));
        }
        if (StrUtil.isNotBlank(result)) {
            piCriteria.andResultEqualTo(Integer.parseInt(result));
        }
        piCriteria.andIsDeleteEqualTo(0);
        piExample.setOrderByClause("operation_time desc");
        Page<PartInventory> page = PageHelper.startPage(pageNum, pageSize);
        List<PartInventory> piList = partInventoryMapper.selectByExample(piExample);
        List<Map<String, Object>> list = new ArrayList<>();
        for (PartInventory pi : piList) {
            Map<String, Object> map = new HashMap<>();
            map.put("id", pi.getId());
            map.put("inventoryCode", pi.getInventoryCode());
            map.put("operationEmployeeName", SystemData.employeeMap.get(pi.getOperationEmployeeId()).getEmployeeName());
            map.put("operationTime", DateUtil.formatDateTime(pi.getOperationTime()));
            map.put("state", pi.getState());
            map.put("warehouse", warehouseMap.get(pi.getWarehouse()));
            map.put("remark", pi.getRemark());
            map.put("result", pi.getResult());
            map.put("startTime", pi.getStartTime() == null ? "" : DateUtil.formatDateTime(pi.getStartTime()));
            map.put("endTime", pi.getEndTime() == null ? "" : DateUtil.formatDateTime(pi.getEndTime()));
            list.add(map);
        }
        return DataResult.build9100(new GridData(page.getTotal(), list));
    }

    @Override
    public DataResult selectPartInventoryOne(LoginInfo li, long id) throws Exception {
        Map<Long, String> warehouseMap = new HashMap<>();
        List<PartWarehouse> pwList = partWarehouseMapper.selectByExample(null);
        for (PartWarehouse pw : pwList) {
            warehouseMap.put(pw.getId(), pw.getName());
        }

        List<Map<String, Object>> partList = new ArrayList<>();
        PartInventoryDetailExample pidExample = new PartInventoryDetailExample();
        pidExample.createCriteria().andInventoryIdEqualTo(id);
        pidExample.setOrderByClause("id");
        List<PartInventoryDetail> pidList = partInventoryDetailMapper.selectByExample(pidExample);
        for (PartInventoryDetail pid : pidList) {
            PartStock ps = partStockMapper.selectByPrimaryKey(pid.getStockId());
            PartInfo pi = partInfoMapper.selectByPrimaryKey(ps.getPartId());
            Map<String, Object> partMap = new HashMap<>();
            partMap.put("id", pi.getId());
            partMap.put("code", pi.getCode());
            partMap.put("name", pi.getName());
            partMap.put("brand", pi.getBrand());
            partMap.put("specs", pi.getSpecs());
            partMap.put("unit", pi.getUnit());
            partMap.put("stockId", pid.getStockId());
            partMap.put("warehouse", warehouseMap.get(ps.getWarehouse()));
            partMap.put("locator", warehouseMap.get(ps.getLocator()));
            partMap.put("stock", ps.getStock());
            partMap.put("newStock", pid.getNewStock());
            partList.add(partMap);
        }

        PartInventory pi = partInventoryMapper.selectByPrimaryKey(id);
        Map<String, Object> map = new HashMap<>();
        map.put("id", pi.getId());
        map.put("inventoryCode", pi.getInventoryCode());
        map.put("operationEmployeeName", SystemData.employeeMap.get(pi.getOperationEmployeeId()).getEmployeeName());
        map.put("warehouse", pi.getWarehouse());
        map.put("remark", pi.getRemark());
        map.put("partList", partList);
        return DataResult.build9100(map);
    }

    @Override
    public DataResult insertPartInventory(LoginInfo li, long warehouse, String remark, String data) throws Exception {
        Date date = new Date();
        PartInventory newPi = new PartInventory();
        newPi.setInventoryCode("SP-BJPD-" + DateUtil.format(date, "yyyyMMdd") + "-" + getPartCode("PART_INVENTORY_NUMBER"));
        newPi.setOperationEmployeeId(li.getLoginEmployeeId());
        newPi.setOperationTime(date);
        newPi.setState(1);
        newPi.setWarehouse(warehouse);
        newPi.setRemark(StrUtil.isBlank(remark) ? "" : remark);
        newPi.setIsDelete(0);
        newPi.setResult(0);
        partInventoryMapper.insert(newPi);
        if (StrUtil.isBlank(data)) {
            return DataResult.build9100();
        }
        for (Object obj : JSONUtil.parseArray(data)) {
            JSONObject jsonObj = JSONUtil.parseObj(obj);
            long stockId = jsonObj.getLong("stockId");
            int newStock = jsonObj.getInt("newStock");
            PartStock ps = partStockMapper.selectByPrimaryKey(stockId);
            if (ps.getWarehouse() != warehouse) {
                break;
            }
            PartInventoryDetail newPid = new PartInventoryDetail();
            newPid.setInventoryId(newPi.getId());
            newPid.setStockId(stockId);
            newPid.setOldStock(ps.getStock());
            newPid.setNewStock(0);
            partInventoryDetailMapper.insert(newPid);
        }
        return DataResult.build9100();
    }

    @Override
    public DataResult updatePartInventory(LoginInfo li, long id, long warehouse, String remark, String data) throws Exception {
        PartInventory pi = partInventoryMapper.selectByPrimaryKey(id);
        if (pi.getState() != 1) {
            return DataResult.build9250("备件盘点单已开始或盘点结束，无法修改");
        }
        pi.setWarehouse(warehouse);
        pi.setRemark(StrUtil.isBlank(remark) ? "" : remark);
        partInventoryMapper.updateByPrimaryKeySelective(pi);

        PartInventoryDetailExample pidExample = new PartInventoryDetailExample();
        pidExample.createCriteria().andInventoryIdEqualTo(id);
        partInventoryDetailMapper.deleteByExample(pidExample);
        if (StrUtil.isBlank(data)) {
            return DataResult.build9100();
        }
        for (Object obj : JSONUtil.parseArray(data)) {
            JSONObject jsonObj = JSONUtil.parseObj(obj);
            long stockId = jsonObj.getLong("stockId");
            int newStock = jsonObj.getInt("newStock");
            PartStock ps = partStockMapper.selectByPrimaryKey(stockId);
            if (ps.getWarehouse() != warehouse) {
                break;
            }
            PartInventoryDetail newPid = new PartInventoryDetail();
            newPid.setInventoryId(id);
            newPid.setStockId(stockId);
            newPid.setOldStock(ps.getStock());
            newPid.setNewStock(ps.getStock());
            partInventoryDetailMapper.insert(newPid);
        }
        return DataResult.build9100();
    }

    @Override
    public DataResult deletePartInventory(LoginInfo li, long id) throws Exception {
        PartInventory pi = partInventoryMapper.selectByPrimaryKey(id);
//        if (pi.getState() != 1) {
//            return DataResult.build9250("删除失败，备件盘点单已开始或盘点结束");
//        }
        pi.setIsDelete(1);
        partInventoryMapper.updateByPrimaryKeySelective(pi);
        return DataResult.build9100();
    }

    @Override
    public DataResult updatePartInventoryStart(LoginInfo li, long id) throws Exception {
        PartInventory pi = partInventoryMapper.selectByPrimaryKey(id);
        if (pi.getState() != 1) {
            return DataResult.build9250("开始失败，备件盘点单已开始或盘点结束");
        }

        PartInventoryDetailExample pidExample = new PartInventoryDetailExample();
        pidExample.createCriteria().andInventoryIdEqualTo(pi.getId());
        List<PartInventoryDetail> pidList = partInventoryDetailMapper.selectByExample(pidExample);
        if (pidList.size() == 0) {
            return DataResult.build9250("开始失败，无备件数据");
        }
        for (PartInventoryDetail pid : pidList) {
            PartStock ps = partStockMapper.selectByPrimaryKey(pid.getStockId());
            if (!ps.getWarehouse().equals(pi.getWarehouse())) {
                return DataResult.build9250("开始失败，备件盘点单中有异常仓库的备件");
            }
        }

        pi.setState(2);
        pi.setStartTime(new Date());
        partInventoryMapper.updateByPrimaryKeySelective(pi);
        return DataResult.build9100();
    }

    @Override
    public DataResult updatePartInventoryData(LoginInfo li, long id, String data) throws Exception {
        PartInventory pi = partInventoryMapper.selectByPrimaryKey(id);
        if (pi.getState() != 2) {
            return DataResult.build9250("该备件盘点单还未开始盘点");
        }
        for (Object obj : JSONUtil.parseArray(data)) {
            JSONObject jsonObj = JSONUtil.parseObj(obj);
            long stockId = jsonObj.getLong("stockId");
            int newStock = jsonObj.getInt("newStock");

            PartInventoryDetailExample pidExample = new PartInventoryDetailExample();
            pidExample.createCriteria().andStockIdEqualTo(stockId).andInventoryIdEqualTo(pi.getId());
            List<PartInventoryDetail> pidList = partInventoryDetailMapper.selectByExample(pidExample);
            if (pidList.size() != 1) {
                return DataResult.build9250("备件盘点单数据错误");
            }

            PartInventoryDetail pid = pidList.get(0);
            pid.setNewStock(newStock);
            partInventoryDetailMapper.updateByPrimaryKeySelective(pid);
        }
        return DataResult.build9100();
    }

    @Override
    public DataResult updatePartInventoryEnd(LoginInfo li, long id) throws Exception {
        PartInventory pi = partInventoryMapper.selectByPrimaryKey(id);
        if (pi.getState() != 2) {
            return DataResult.build9250("该备件盘点单还未开始盘点");
        }
        int result = 1;
        Map<Long, Integer> partMap = new HashMap<>();
        List<PartOrderDetail> orderInMap = new ArrayList<>();
        List<PartOrderDetail> orderOutMap = new ArrayList<>();
        PartInventoryDetailExample pidExample = new PartInventoryDetailExample();
        pidExample.createCriteria().andInventoryIdEqualTo(id);
        List<PartInventoryDetail> pidList = partInventoryDetailMapper.selectByExample(pidExample);
        for (PartInventoryDetail pid : pidList) {
            PartStock ps = partStockMapper.selectByPrimaryKey(pid.getStockId());
            ps.setStock(pid.getNewStock());
            partStockMapper.updateByPrimaryKeySelective(ps);
            int subNum = pid.getNewStock() - pid.getOldStock();
            if (partMap.containsKey(ps.getPartId())) {
                partMap.put(ps.getPartId(), partMap.get(ps.getPartId()) + subNum);
            } else {
                partMap.put(ps.getPartId(), subNum);
            }
            if (!pid.getOldStock().equals(pid.getNewStock())) {
                result = 2;
            }

            if (subNum != 0) {
                PartOrderDetail newPod = new PartOrderDetail();
                newPod.setPartId(ps.getPartId());
                newPod.setStockId(pid.getStockId());
                newPod.setOutApplyNum(0);
                newPod.setInOutNum(subNum);
                if (subNum > 0) {
                    orderInMap.add(newPod);
                } else {
                    orderOutMap.add(newPod);
                }
            }
        }
        for (long partId : partMap.keySet()) {
            if (partMap.get(partId) != 0) {
                PartInfo p = partInfoMapper.selectByPrimaryKey(partId);
                p.setStock(p.getStock() + partMap.get(partId));
                partInfoMapper.updateByPrimaryKeySelective(p);
            }
        }
        Date date = new Date();
        pi.setState(3);
        pi.setResult(result);
        pi.setEndTime(date);
        partInventoryMapper.updateByPrimaryKeySelective(pi);

        // 新增出入库单数据
        if (!orderInMap.isEmpty()) {
            PartOrder newPo = new PartOrder();
            newPo.setOrderCode("SP-BJRK-" + DateUtil.format(date, "yyyyMMdd") + "-" + getPartCode("PART_IN_NUMBER"));
            newPo.setOrderType(0);
            newPo.setState(0);
            newPo.setOperationEmployeeId(li.getLoginEmployeeId());
            newPo.setOperationTime(date);
            newPo.setInOutType(2);
            newPo.setApplyId(0L);
            newPo.setBusinessId(pi.getId());
            newPo.setBusinessCode(pi.getInventoryCode());
            partOrderMapper.insert(newPo);
            for (PartOrderDetail pod : orderInMap) {
                pod.setOrderId(newPo.getId());
                partOrderDetailMapper.insert(pod);
            }
        }
        if (!orderOutMap.isEmpty()) {
            PartOrder newPo = new PartOrder();
            newPo.setOrderCode("SP-BJCK-" + DateUtil.format(date, "yyyyMMdd") + "-" + getPartCode("PART_OUT_NUMBER"));
            newPo.setOrderType(1);
            newPo.setState(0);
            newPo.setOperationEmployeeId(li.getLoginEmployeeId());
            newPo.setOperationTime(date);
            newPo.setInOutType(6);
            newPo.setApplyId(0L);
            newPo.setBusinessId(pi.getId());
            newPo.setBusinessCode(pi.getInventoryCode());
            partOrderMapper.insert(newPo);
            for (PartOrderDetail pod : orderOutMap) {
                pod.setOrderId(newPo.getId());
                partOrderDetailMapper.insert(pod);
            }
        }
        return DataResult.build9100();
    }

    @Override
    public long insertOrderOut(LoginInfo li, long orderId, String orderCode, Map<Long, Integer> partMap) throws Exception {
//        for (long partId : partMap.keySet()) {
//            PartInfo pi = partInfoMapper.selectByPrimaryKey(partId);
//            if (partMap.get(partId) > pi.getStock() - pi.getTransitStock()) {
//                return 0L;
//            }
//        }

        Date date = new Date();
        PartOrder newPo = new PartOrder();
        newPo.setOrderCode("SP-BJCK-" + DateUtil.format(date, "yyyyMMdd") + "-" + getPartCode("PART_OUT_NUMBER"));
        newPo.setOrderType(1);
        newPo.setState(1);
        newPo.setOperationEmployeeId(li.getLoginEmployeeId());
        newPo.setOperationTime(date);
        newPo.setInOutType(5);
        newPo.setApplyId(0L);
        newPo.setBusinessId(orderId);
        newPo.setBusinessCode(orderCode);

        List<PartOrderDetail> partOrderDetailList = new ArrayList<>();
        Map<Long,Integer> partNumMap = new HashMap<>();
        for (long partId : partMap.keySet()) {
            int needPartNum = partMap.get(partId);
            List<PartStock> psList = getPartStockListByPartId(partId);

            for (PartStock ps : psList) {
                if (needPartNum <= 0) {
                    break;
                }
                int partNum = ps.getStock();
                if (needPartNum < ps.getStock()) {
                    partNum = needPartNum;
                }
                needPartNum -= ps.getStock();

                PartOrderDetail newPod = new PartOrderDetail();
                newPod.setPartId(ps.getPartId());
                newPod.setStockId(ps.getId());
                newPod.setOutApplyNum(partNum);
                newPod.setInOutNum(0);
                if(partNum > 0){
                    partOrderDetailList.add(newPod);
                }
                //partOrderDetailMapper.insert(newPod);
            }
            if(needPartNum > 0){
                // 剩下的从内库 出库
                partNumMap.put(partId,needPartNum);
            }
        }
        Long reId = 0L;
        if(!partOrderDetailList.isEmpty()) {
            partOrderMapper.insert(newPo);
            for(PartOrderDetail partOrderDetail : partOrderDetailList){
                partOrderDetail.setOrderId(newPo.getId());
                partOrderDetailMapper.insert(partOrderDetail);
            }
            reId = newPo.getId();
        }
        Long id = createOutInnerStockBill(partNumMap,newPo,li);
        return reId == 0L ? id : reId;
    }

    @Override
    public DataResult selectPartOrderOneByRepair(LoginInfo li, long id) throws Exception {
        List<Map<String, Object>> partList = new ArrayList<>();

        PartOrderExample poExample = new PartOrderExample();
        poExample.createCriteria().andBusinessIdEqualTo(id).andOrderTypeEqualTo(1).andInOutTypeEqualTo(4);
        poExample.setOrderByClause("operation_time desc");
        List<PartOrder> poList = partOrderMapper.selectByExample(poExample);

        List<PartInnOrder> partInnOrders = partInnOrderMapper.selectPartInnOrdersByBusinessId(id);
        if (poList.isEmpty() && partInnOrders.isEmpty()) {
            return DataResult.build9100(partList);
        }

        Map<Long, String> warehouseMap = new HashMap<>();
        List<PartWarehouse> pwList = partWarehouseMapper.selectByExample(null);
        for (PartWarehouse pw : pwList) {
            warehouseMap.put(pw.getId(), pw.getName());
        }
        PartOrderDetailExample podExample = new PartOrderDetailExample();
        podExample.createCriteria().andOrderIdEqualTo(poList.get(0).getId());
        List<PartOrderDetail> podList = partOrderDetailMapper.selectByExample(podExample);
        List<PartInnStock> partInnStocks = new ArrayList<>();
        List<Long> partIdList = podList.stream().map(PartOrderDetail::getPartId).collect(Collectors.toList());
        if (CollUtil.isNotEmpty(partIdList)) {
            partInnStocks = partInnStockMapper.selectByPartIdList(partIdList);
        }

        for (PartOrderDetail pod : podList) {
            PartInfo pi = partInfoMapper.selectByPrimaryKey(pod.getPartId());
            PartStock ps = partStockMapper.selectByPrimaryKey(pod.getStockId());
            Map<String, Object> partMap = new HashMap<>();
            Integer stock = this.findPartInnStocks(partInnStocks,pod.getPartId());
            partMap.put("id", pi.getId());
            partMap.put("code", pi.getCode());
            partMap.put("name", pi.getName());
            partMap.put("brand", pi.getBrand());
            partMap.put("specs", pi.getSpecs());
            partMap.put("unit", pi.getUnit());
            partMap.put("stock", pi.getStock());
            partMap.put("useStock", (pi.getStock() + stock) - pi.getTransitStock());
            partMap.put("stockId", pod.getStockId());
            partMap.put("warehouse", warehouseMap.get(ps.getWarehouse()));
            partMap.put("locator", warehouseMap.get(ps.getLocator()));
            partMap.put("outApplyNum", pod.getOutApplyNum());
            partMap.put("num", Math.abs(pod.getInOutNum()));
            partList.add(partMap);
        }

        if(!partInnOrders.isEmpty()){
            PartInnOrder partInnOrder = partInnOrders.get(0);
            List<PartInnOrderDetailVO> partInnOrderDetailVOList = partInnOrderDetailMapper.selectOutNum(partInnOrder.getId());
            if(!partInnOrderDetailVOList.isEmpty()) {



                for (PartInnOrderDetailVO partInnOrderDetailVO : partInnOrderDetailVOList) {
                    PartInfo pi = partInfoMapper.selectByPrimaryKey(partInnOrderDetailVO.getId());
                    Map<String, Object> partMap = new HashMap<>();

                    Integer stock = this.findPartInnStocks(partInnStocks,pi.getId());
                    partMap.put("id", pi.getId());
                    partMap.put("code", pi.getCode());
                    partMap.put("name", pi.getName());
                    partMap.put("brand", pi.getBrand());
                    partMap.put("specs", pi.getSpecs());
                    partMap.put("unit", pi.getUnit());
                    partMap.put("stock", pi.getStock());
                    partMap.put("useStock", (pi.getStock() + stock) - pi.getTransitStock());
                    partMap.put("stockId", 0);
                    partMap.put("warehouse", "库内仓库");
                    partMap.put("locator", "库内库位");
                    partMap.put("outApplyNum", partInnOrderDetailVO.getInOutNum());
                    partMap.put("num", partInnOrderDetailVO.getInOutNum());
                    partList.add(partMap);
                }
            }
        }

        return DataResult.build9100(partList);
    }

    private String getPartCode(String key) throws Exception {
        SystemParameter sp = systemParameterMapper.selectByPrimaryKey(key);
        int num = Integer.parseInt(sp.getParameterValue()) + 1;
        String code;
        if (num < 10) {
            code = "000" + num;
        } else if (num < 100) {
            code = "00" + num;
        } else if (num < 1000) {
            code = "0" + num;
        } else {
            code = "" + num;
        }
        sp.setParameterValue(num + "");
        systemParameterMapper.updateByPrimaryKey(sp);
        return code;
    }

    private void insertPartApplyLog(long applyId, long employeeId, Date date, int operation, String operationDesc) throws Exception {
        PartApplyLog newPal = new PartApplyLog();
        newPal.setApplyId(applyId);
        newPal.setEmployeeId(employeeId);
        newPal.setOperationTime(date);
        newPal.setOperation(operation);
        newPal.setOperationDesc(operationDesc);
        partApplyLogMapper.insert(newPal);
    }

    private boolean isPartInventory(long warehouse) {
        PartInventoryExample piExample = new PartInventoryExample();
        piExample.createCriteria().andIsDeleteEqualTo(0).andStateEqualTo(2).andWarehouseEqualTo(warehouse);
        return partInventoryMapper.countByExample(piExample) > 0;
    }


}
